home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / CHAINDOC.ZIP / CHAIN4.DOC next >
Text File  |  1995-06-17  |  25KB  |  566 lines

  1.  
  2.       ╒═══════════════════════════════════════════════════════════════╗
  3.       │■                                                            ■ ║
  4.       │                                                               ║
  5.       │  █████████░                   ██░                             ║
  6.       │  ██░    ██░ ██░   ██░ ██████░ ██░     ████████░ ██░     ██░   ║
  7.       │  ██░    ██░ ██░   ██░   ██░   ██░     ██░   ██░ ██░     ██░   ║
  8.       │  ██░    ██░ ██░   ██░   ██░   ██░     ████████░ ██░     ██░   ║
  9.       │  ██░    ██░ ██░   ██░   ██░   ██░     ██░   ██░ ██░ ██░ ██░   ║
  10.       │  █████████░ ████████░   ██░   ██████░ ██░   ██░  ███░ ███░    ║
  11.       │                                                               ║
  12.       │                        T ∙ R ∙ I ∙ A ∙ D                      ║
  13.       │■                                                            ■ ║
  14.       └───────────────────────────────────────────────────────────────╜
  15.                                ╔══════════════╗
  16.                                ║ ∙ PRESENTS ∙ ║
  17.                                ╚══════════════╝
  18.  
  19.  
  20.                         Chain-4 Documentary Version 2.0
  21. ───────────────────────────────────────────────────────────────────────────────
  22.   Written By : Vulture                    Total Files  : 2
  23.   File Type  : Textfile                   Release Date : 17th of June 1995
  24.   Difficulty : Medium level               Filename     : CHAINDOC.ZIP
  25. ───────────────────────────────────────────────────────────────────────────────
  26.  
  27. Note: This is version 2.0. It includes some pascal procedures at the end of
  28.       the document.
  29.  
  30. I started writing this little document as a helpfile for myself coz I think
  31. a great way to learn is writing things down. I found myself having troubles
  32. understanding the assembler code found in various trainers so I thought it
  33. was a good idea to make a textfile wich covered some of the main tricks there
  34. are concerning chain-4 code. Worked out great! Infact, I think this file can
  35. be of great help to all starting gfxcoders out there, so I have decided to
  36. release it into the public domain. There are already lots of docs available
  37. on the subject but there's always room for one more, eh? :)
  38. Hmm, I will assume you know a little about VGA programming and assembler code.
  39. If you don't know anything about it yet, this doc might be a little hard to
  40. understand. If you are already a chain-4 guru, you can go back to sleep coz
  41. this is probably too easy for you. This document describes the very basics of
  42. chain-4. But anyway, enough of thiz cr*p. . . on with the real stuff :)
  43.  
  44.  
  45. =-=-=-=-=-=-=-=-=-=-=-=-= CHAIN-4 VIDEOMODE DOCFILE =-=-=-=-=-=-=-=-=-=-=-=-=-
  46.  
  47. =-= What is chain-4 ? =-=
  48.  
  49. Most VGA intros are written in mode 13h. This is 320*200*256 mode. The memory
  50. in this mode is lineair and thus fairly easy to handle. The resolution isn't
  51. that great but for most intros it's enough. One can make very cewl graphics
  52. in this mode. So all in all this is a great mode to use. However, a major
  53. disadvantage is the fact that only 64 kB of VGA memory can be accessed.
  54. This is the entire screen (320*200 = almost 64kB = 1 page) you see in front
  55. of you. So, when you use this mode you aren't using the full standard 256kB
  56. of memory present on the VGA-card but just 64kB. For most people mode 13h is
  57. sufficient but for the more serious coders it just isn't enough. They want to
  58. use the full 256 kB of memory available for e.g fast pageflipping, full screen
  59. scrolling and lots of other cewl things. Here we go:
  60. Chain-4 is a method of accessing 256 kB of memory on a standard VGA-card.
  61. When using chain-4 the VGA memory is unchained wich bassicly means that the
  62. memory is no longer lineair as were the case in standard mode 13h. Due to VGA
  63. hardware this gives us 256 kB of memory. On a chain-4 screen pixels are placed
  64. on so-called bitplanes. Normally there are four pages (=planes) available,
  65. each 64kB big. This is coz a segment can only be 64 kB big. And 4*64kB=256kB.
  66. It is also possible to 'tweak' the videomode and get into higher resolutions.
  67. E.g 320*240*256. This results in you having less pages available because
  68. you have more pixels on a page. However, in this doc I will not go into
  69. tweaking the videomode but stay with the basics.
  70. Take a look at the following diagram. It shows a possible chain-4 screen.
  71.  
  72.   0            X         640
  73.    ┌──────────────────────┐
  74.    │      =>┌────────┐    │
  75.    │        │  View  │    │   The viewport always shows 1/4=64k of the
  76.    │        │  Port  │    │   total chain-4 screen. In this case the
  77.    │        │        │    │   chain-4 screen is 2 pages width and 2
  78.  Y │        └────────┘    │   pages high. The total chain-4 screen can
  79.    │                      │   be anything that adds up to 4 pages.
  80.    │   Chain-4 screen     │   More of this l8r downbelow.
  81.    │                      │
  82.    └──────────────────────┘
  83.  400
  84.  
  85. The memory layout of the chain-4 screen is rather different from the normal
  86. MCGA gfxmode. Like I said previously, the memory is divided into 4 bitplanes.
  87. Each 64 kB big because of segmentlimitations. The following picture should
  88. clear some things. Suppose you are plotting pixels with colors 0 to 9.
  89. If the color has reached value 9, it's set to 0 again. Take a look:
  90.  
  91. The standard lineair MCGA mode gives us:
  92.  
  93.              ┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
  94.              │00│01│02│03│04│05│06│07│08│09│00│01│...etc...
  95.  
  96.  
  97. In unchained VGA memory, the screen will be represented as follows:
  98.  
  99. Plane 0:
  100.  
  101.     Address:  0         10                70       79 (Not 319 anymore)
  102.              ┌──────────────────────────────────────┐
  103.              │0482604826048260    .....   0482604826│
  104.              │                                      │
  105.  
  106. Plane 1:
  107.  
  108.     Address:  0         10                70       79
  109.              ┌──────────────────────────────────────┐
  110.              │1593715937159371    .....   1593715937│
  111.              │                                      │
  112.  
  113. Plane 2:
  114.  
  115.     Address:  0         10                70       79
  116.              ┌──────────────────────────────────────┐
  117.              │2604826048260482    .....   2604826048│
  118.              │                                      │
  119.  
  120. Plane 3:
  121.  
  122.     Address:  0         10                70       79
  123.              ┌──────────────────────────────────────┐
  124.              │3715937159371593    .....   3715937159│
  125.              │                                      │
  126.  
  127. This means that when you point to an address, you are actually pointing to
  128. the addresses of FOUR neighbouring pixels. To be more exact: address 0
  129. points to pixels 0,1,2 and 3, each on different planes. Adress 1 points to
  130. pixels 4,5,6 and 7, etcetera. Now, before writing the pixel, you will have to
  131. enable the plane of the pixel you want. If pixel P is in plane I, pixel P+1
  132. will be in plane (I+1)%4. The screenwidth is now set to 80 instead of 320.
  133. This should make perfect sence. Think about it. One adress points to 4 pixels.
  134. Multiply 80 by 4 and you'll get your basic 320 again. And there are still 320
  135. pixels across visible. 200 pixels in height remains the same. Simple!
  136.  
  137. So, that's a bit different, eh? Also more difficult to code. But don't let it
  138. scare you. The advantages you gain from using this mode are well worth the
  139. effort. And besides, you have this doc so it's not that hard anymore :)
  140.  
  141. This document explains how to access the unchained videomode, enable
  142. planes for writing and reading, moving across the screens and putting
  143. pixels on the screens.
  144.  
  145. A. How to access the unchained VGA mode.
  146. B. How to activate the plane we want to write to.
  147. C. How to activate the plane we want to read from.
  148. D. How to move across the various planes (screens).
  149. E. How to place a pixel on the chain-4 screen.
  150. F. Various pascal procedures concerning this code.
  151. G. Closing words.
  152.  
  153. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  154.  
  155. A. HOW TO ACCESS THE UNCHAINED VGA MODE.
  156.  
  157. This is done by setting various vga registers. The code below is very
  158. basic and can be expanded but it's suitable for our needs right now.
  159.  
  160. 1. Get into MCGA mode.
  161.    Done by a simple bios-call.
  162.  
  163.    mov   ax,0013h          ; Videomode 13h  320*200*256
  164.    int   10h               ; Set the mode
  165.  
  166. 2. Unchain VGA-mode.
  167.    This is done by turning the 3rd bit in index 4 of the sequencer off.
  168.  
  169.    mov   dx,03c4h         ; Sequencer Address Register
  170.    mov   al,4             ; Index 4 - Memory mode
  171.    out   dx,al            ; Select it
  172.    inc   dx               ; 03c5h - Here we set the mem mode.
  173.    in    al,dx            ; Get settings inside register
  174.    and   al,11110111b     ; Disable 3rd bit will give us chain-4
  175.    or    al,00000100b     ; Bit 2 enabled => no odd/even-scheme
  176.    out   dx,al            ; Inform VGA
  177.  
  178. 3. Turn off doubleword mode by setting the Underline Location register
  179.    Use CRT controllers port 3d4h index 14h
  180.  
  181.    mov   dx,3d4h
  182.    mov   al,14h           ; Select index 14 "Underline Location Register"
  183.    out   dx,al
  184.    inc   dx
  185.    in    al,dx
  186.    and   al,10111111b     ; Bit 6 := 0 => Disable double word adressing
  187.    out   dx,al
  188.  
  189. 4. Turn off word adressing by setting the Mode Control register.
  190.    Now use CRT controllers port 3d4h index 17h
  191.  
  192.    mov   dx,3d4h
  193.    mov   al,17h           ; Mode Control Register
  194.    out   dx,al
  195.    inc   dx
  196.    in    al,dx            ; Get what's in the register
  197.    or    al,01000000b     ; Bit 6 := 1
  198.    out   dx,al            ; Thus disabling wordmode
  199.  
  200. 5. Set the logical screen width.
  201.    To do this, use the CRT controllers port 3d4h index 13h.
  202.  
  203.    mov   dx,3d4h         ; Select the port
  204.    mov   al,13h          ; Select index Logical Screen Width
  205.    out   dx,al           ; Inform VGA about it
  206.    inc   dx              ; Increase port value
  207.    mov   al,[Size]       ; Set the size
  208.    out   dx,al           ; Give info to VGA
  209.  
  210. Like I stated previously, the chain-4 screen can be any size that adds
  211. up to 4 screens with a screen being 320*200 pixels large (=64kB).
  212. Size * 8 is how many pixels across there are on the chain-4 screen.
  213. Examine this:
  214. Size = 40  =>  320 pixels across = 1 screen across, 4 screens down
  215. Size = 80  =>  640 pixels across = 2 screens across, 2 screens down
  216. Size = 160 => 1280 pixels across = 4 screens across, 1 screen down
  217. These are all possibilities. Remember, only 320 pixels across are visible.
  218. We need to know the size of the screen for almost all dealings with the
  219. chain-4 screen so it's clever to put the size in a constant. Just like I did
  220. in the example code.
  221.  
  222. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  223.  
  224. B. HOW TO ACTIVATE THE PLANE WE WANT TO WRITE TO.
  225.  
  226. Before we can plot a pixel on the chain-4 screen, we have to select and
  227. activate the plane we want to write to. You must alter the 4 least signifi-
  228. cant bits (bits 0,1,2 and/or 3) in index 2 (set/reset enable register) of
  229. the graphics controller. This is done as follows:
  230.  
  231. 1. Select gfx controller: port 3ceh
  232.    mov   dx,3ceh
  233. 2. Select index 2 => Set/reset enable register
  234.    mov   al,02
  235. 3. Pass info to VGA
  236.    out   dx,al
  237. 4. Increase port value
  238.    inc   dx
  239. 5. Select plane for writing      ; 1 = on  0 = off
  240.    mov   al,00000001b            ; enables plane 0    (byte=76543210)
  241. 6. Give info to VGA
  242.    out   dx,al
  243.  
  244. So, to enable plane 0 for writing:
  245.  
  246.    mov   dx,3ceh          ; Select port
  247.    mov   al,02            ; Select index
  248.    out   dx,al            ; Give info to VGA
  249.    inc   dx               ; Increase port value (datafield)
  250.    mov   al,00000001b     ; Enable plane 0   (bit 0 is now set)
  251.    out   dx,al            ; Inform VGA 'bout thiz
  252.  
  253. For all other planes the same code can be used. Just change the MOV command.
  254. You can also use the AND command for this purpose. Play with it and learn.
  255. All 4 planes can be set for writing to so you can set 4 pixels at the same
  256. time with just 1 movsb. Simply enable the 4 least significant bits at once.
  257. Wow! This is fast...  :)
  258.  
  259. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  260.  
  261. C. HOW TO ACTIVATE THE PLANE WE WANT TO READ FROM.
  262.  
  263. Same goes for reading. First activate the plane and then read the pixel.
  264. Do it like thiz:
  265.  
  266. 1. Select gfx controller port 3ceh
  267.    mov   dx,3ceh
  268. 2. Select index
  269.    mov   al,04                  ; Read plane index
  270. 3. Inform VGA about this
  271.    out   dx,al
  272. 4. Increase port value
  273.    inc   dx
  274. 5. Select plane for reading
  275.    mov   al,00000000b           ; Select plane 0 for reading
  276. 6. Inform VGA
  277.    out   dx,al
  278.  
  279. Bits 0 and 1 must be altered to select a plane for reading. (byte=76543210)
  280. 00: plane 0 read enable.
  281. 01: plane 1 read enable.
  282. 10: plane 2 read enable.
  283. 11: plane 3 read enable.
  284. As you might have guessed, you cannot read from all planes at the same time.
  285.  
  286. So, to enable plane 0 for reading, you'd do the following:
  287.  
  288.    mov   dx,3ceh          ; Select port
  289.    mov   al,04            ; Select index
  290.    out   dx,al            ; Give info to VGA
  291.    inc   dx               ; Increase port value
  292.    mov   al,00000000b     ; Enable plane 0 (since all bits are zero)
  293.    out   dx,al            ; Inform VGA
  294.  
  295. That's it. Easy enough, eh?  :)
  296.  
  297. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  298.  
  299. D. HOW TO MOVE ACROSS THE VARIOUS PLANES (=screens).
  300.  
  301. We move across the screens by changing the upperleft adress of the viewport.
  302.  
  303. ┌─────────────────────────────────────┐
  304. │      =>┌────────┐                   │
  305. │        │  View  │   Chain-4         │ The viewport always shows 1/4 of the
  306. │        │  Port  │   Screen          │ total Chain-4 screen.
  307. │        │        │                   │
  308. │        └────────┘                   │
  309. └─────────────────────────────────────┘
  310.  
  311. This is of course an excellent way to scroll. Having a big picture on two or
  312. more screens and then moving the viewport over the screens is much faster than
  313. trying to scroll the screen in plain MCGA mode. Just takes a view port-writes.
  314. To do this trick, we have to use the Crt controller port 03d4h. We need index
  315. 0Ch and 0Dh. That's Start Adress High and Start Adress Low.
  316.  
  317. 1. Select Crt port
  318.    mov   dx,03d4h
  319. 2. Select index 0Ch
  320.    mov   al,0Ch             ; Start adress High
  321. 3. Inform VGA
  322.    out   dx,al
  323. 4. Increase port-value
  324.    inc   dx                 ; Data register
  325. 5. Move high byte into al
  326.    mov   al,bh              ; Assuming bx contains total adress
  327. 6. Change VGA settings
  328.    out   dx,al
  329.  
  330. Now we have set the high byte of the total adress. Only thing left to do is
  331. set the low byte too. This is done the similar way except we use index 0Dh.
  332.  
  333. 1. Select Crt port
  334.    mov   dx,03d4h
  335. 2. Select index 0Dh
  336.    mov   al,0Dh             ; Start adress Low
  337. 3. Inform VGA
  338.    out   dx,al
  339. 4. Increase port-value
  340.    inc   dx
  341. 5. Move low byte into al
  342.    mov   al,bl              ; Assuming bx contains total adress
  343. 6. Change VGA settings
  344.    out   dx,al
  345.  
  346. Now we have set the total new adress of the viewport and have moved the
  347. entire viewport across the entire chain-4 screen. E.g you can go into a loop
  348. where you let a picture bounce on the bottom of the screen by changing the
  349. startingadress of the viewport. That would be pretty cewl, eh? :)
  350.  
  351. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  352.  
  353. E. HOW TO PLACE PIXELS ON THE CHAIN-4 SCREEN.
  354.  
  355. Ofcourse we want to plot pixels on the screen. But since we are dealing with
  356. various planes, this is not so simple as on a MCGA screen. We have to know
  357. on wich plane we want to plot the pixel and howfar into the plane we must be.
  358. To find the plane we wish to plot on, we do this calculation (x mod 4), and
  359. the x-coordinate on that plane is found by (x div 4). We work out our y by
  360. multiplying it by the size of our chain-4 screen. This all might sound a bit
  361. strange. Why not make a small program to see what I mean? Anyway, in steps:
  362.  
  363. 1. Multiply Y by our screensize (40,80 or 160)
  364.    y*size
  365. 2. Find out hofar in the plane we must be
  366.    x div 4
  367. 3. Finalize location
  368.    y:=y+x
  369. 4. Find out on wich plane to plot
  370.    x mod 4
  371. 5. Set that plane
  372. 6. Plot the pixel
  373.  
  374. And now for the assember code:
  375.  
  376.    mov    ax,[Y]                   ; Put Y in ax
  377.    xor    bx,bx                    ; Reset bx to zero
  378.    mov    bl,[Size]                ; Size in bl (it's a byte!)
  379.    imul   bx                       ; Now ax:=ax*bx => Y:=Y*Size
  380.    shl    ax,1                     ; Multiply by 2 => Y:=Y*2 (Dunno why)
  381.    mov    bx,ax                    ; Save Y-value in bx
  382.    mov    ax,[X]                   ; Move X-value into ax
  383.    mov    cx,ax                    ; And in cx
  384.    shr    ax,2                     ; Divide ax by 4  (x div 4)
  385.    add    bx,ax                    ; Y:=Y+X   bx contains final location
  386.    and    cx,00000011b             ; cl:=0,1,2 or 3  (x mod 4)
  387.    mov    ah,00000001b             ; Start value = plane 0
  388.    shl    ah,cl                    ; E.g plane 2: 00000001 => 00000100
  389.    mov    dx,3c4h                  ; Sequencer Register
  390.    mov    al,2                     ; Select index 2 => plane enable
  391.    out    dx,ax                    ; Enable selected plane
  392.    mov    ax,0a000h                ; VGA segment
  393.    mov    es,ax                    ; es points to VGA
  394.    mov    al,[col]                 ; Color in al
  395.    mov    es:[bx], al              ; Place it
  396.  
  397. This is a complete chain-4 putpixel procedure. You can ofcourse make a pascal
  398. procedure out of it. Look at the next chapter for that one. The procedure can
  399. ofcourse be optimized but then... what can't :)
  400.  
  401. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  402.  
  403. F. VARIOUS PASCAL PROCEDURES CONVERNING THIS CODE.
  404.  
  405. I have included some pascal procedures for you to examine/use. The code works
  406. just fine and you should not have any troubles implementing this in your own
  407. programs.
  408.  
  409. Procedure SetChain4; Assembler;  { Get into Chain-4 videomode }
  410. Asm
  411.    mov   ax,0013h         { Videomode 13h  320*200*256 }
  412.    int   10h              { Set the mode }
  413.  
  414.    mov   dx,03c4h         { Sequencer Address Register }
  415.    mov   al,4             { Index 4 - Memory mode }
  416.    out   dx,al            { Select it }
  417.    inc   dx               { 03c5h - Here we set the mem mode }
  418.    in    al,dx            { Get settings inside register }
  419.    and   al,11110111b     { Disable 3rd bit will give us chain4 }
  420.    or    al,00000100b     { Bit 2 enabled => no odd/even-scheme }
  421.    out   dx,al            { Inform VGA }
  422.  
  423.    mov   dx,3d4h
  424.    mov   al,14h           { Turn off Double Word mode }
  425.    out   dx,al
  426.    inc   dx
  427.    in    al,dx
  428.    and   al,10111111b     { Bit 6 := 0 => Disable double word adressing }
  429.    out   dx,al
  430.    mov   dx,3d4h
  431.    mov   al,17h           { Mode Control Register }
  432.    out   dx,al
  433.    inc   dx
  434.    in    al,dx            { Get what's in the register }
  435.    or    al,01000000b     { Bit 6 := 1 => Address memory as lineair array }
  436.    out   dx,al
  437.  
  438.    mov   dx,3d4h          { Select the port }
  439.    mov   al,13h           { Select the index Logical Screen Width }
  440.    out   dx,al            { Inform VGA about it }
  441.    inc   dx               { Increase port value }
  442.    mov   al,[Size]        { Set the size }
  443.    out   dx,al            { Give info to VGA }
  444. End;
  445.  
  446. Procedure Cls_C4; Assembler;
  447. Asm
  448.    mov   dx,03c4h         { Select port 03c4h }
  449.    mov   al,2             { Map Mask Register }
  450.    out   dx,al
  451.    inc   dx
  452.    mov   al,00001111b     { Select all planes for writing }
  453.    out   dx,al            { So we can clear all planes at once }
  454.  
  455.    mov   ax,0a000h
  456.    mov   es,ax
  457.    xor   di,di            { Set es:di = Screen Mem }
  458.    mov   ax,0             { Color to put = black }
  459.    mov   cx,32768         { 32768 (words) * 2 = 65536 bytes = 1 screen }
  460.  
  461.    cld
  462.    rep   stosw            { Clear it }
  463. End;
  464.  
  465. Procedure SetPixelC4(X,Y:Integer; Color:Byte); Assembler;
  466. Asm
  467.    mov    ax,[Y]                   { Put Y in ax }
  468.    xor    bx,bx                    { Reset bx to zero }
  469.    mov    bl,[Size]                { Size in bl (it's a Byte!) }
  470.    imul   bx                       { Now ax:=ax*bx => Y:=Y*Size }
  471.    shl    ax,1                     { Multiply by 2 => Y:=Y*2 (Dunno why) }
  472.    mov    bx,ax                    { Save Y-value in bx }
  473.    mov    ax,[X]                   { Move X-value into ax }
  474.    mov    cx,ax                    { And in cx }
  475.    shr    ax,2                     { Divide ax by 4  (x div 4) }
  476.    add    bx,ax                    { Y:=Y+X   bx contains final location }
  477.    and    cx,00000011b             { cl:=0,1,2 or 3  (x mod 4) }
  478.    mov    ah,00000001b             { Start value (plane 0) }
  479.    shl    ah,cl                    { Eg plane 2: 00000001 => 00000100 }
  480.    mov    dx,3c4h                  { Sequencer Register }
  481.    mov    al,2                     { Select index 2 => plane enable }
  482.    out    dx,ax                    { Enable selected plane }
  483.    mov    ax,0a000h                { VGA segment }
  484.    mov    es,ax                    { es points to VGA }
  485.    mov    al,[Color]               { Color in al }
  486.    mov    es:[bx], al              { Place it }
  487. End;
  488.  
  489. Procedure MoveTo(X,Y : Integer); Assembler;
  490. Asm
  491.    mov   ax,[Y]           { Y value }
  492.    xor   bx,bx            { Reset bx to zero }
  493.    mov   bl,[Size]        { Size in bl }
  494.    shl   bx,1             { *2 (dunno why) }
  495.    imul  bx               { Multiply Y with size }
  496.    mov   bx,ax            { Save Y into BX }
  497.  
  498.    add   bx,[X]           { Y:=Y+X }
  499.  
  500.    mov   dx,03d4h         { CRTC address register }
  501.    mov   al,0ch           { Start Address High register }
  502.    out   dx,al
  503.    inc   dx
  504.    mov   al,bh            { Send high byte of start address }
  505.    out   dx,al
  506.  
  507.    dec   dx
  508.    mov   al,0dh           { Start Address Low register }
  509.    out   dx,al
  510.    inc   dx
  511.    mov   al,bl            { Send low byte of start address }
  512.    out   dx,al
  513. End;
  514.  
  515. That's it. It should be easy enough to make a small sample-program with these
  516. procedures. Why don't you try to scroll a fullscreen picture with this...
  517.  
  518. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  519.  
  520. G. CLOSING WORDS
  521.  
  522. Thanx must go to Denthor & Eze of Aphyxia and Robert Smith for providing info
  523. on the topic. If you haven't got their documents, I suggest you get them.
  524. They are quite good and can be found on various FTP-sites and BBSses.
  525.  
  526. Hmm, well, the following cr*p is supposed to be stated so here we go:
  527. I (Vulture) take no responsibility for any mistakes found in this document.
  528. So use at your own risk. I have used this code myself and did not have any
  529. problems with it so this code should not give ya a hard time.
  530.  
  531. Wanna contact Outlaw for some reason? Then call one of the Outlaw distros
  532. and leave a message.
  533.  
  534. If U actually use this info, a greet to all people stated above would be
  535. appreciated. A little graditude doesn't hurt, does it? :)
  536.  
  537. One thing left to say. Be carefull doing this kinda stuff when you are a
  538. beginner. Just take it one step at the time. (I did)
  539.  
  540.  
  541.  
  542.           Signed:   Vulture / Outlaw Triad / Cri
  543.  
  544.  
  545. ─────────────────────────┬───────────────────────┬────────────────────────────
  546.  Outlaw Triad Distros :  │  Greetz from Outlaw:  │  Releases sofar:
  547. ─────────────────────────┼───────────────────────┼────────────────────────────
  548.                          │                       │
  549.  ■    Blue Thunder   ■   │   - DemoLisher        │   ■ MESSAGE  (dosscroller)
  550.  ■ +31 (0)36-5346967 ■   │   - ThunderHawk       │
  551.                          │   - Ash               │   ■ VGA-VUL1 (sources)
  552.                          │   - The Machine       │
  553.  ■     FireHouse     ■   │   - X∙N∙TRiC          │   ■ CHAINDOC (textfile)
  554.  ■ +31 (0)58-2661590 ■   │   - Utter Chaos       │
  555.                          │   - Crusher           │   ■ VGA-VUL2 (sources)
  556.                          │                       │
  557.                          │   - Critical          │   ■ BASICDOC (textfile)
  558.      Open for more!      │   - Da Frisian Force  │
  559.                          │   - Tribal            │   + various bbs-intros
  560.                          │                       │
  561. ─────────────────────────┴───────────────────────┴────────────────────────────
  562.  
  563.                    ■ (C) 1995  O∙U∙T∙L∙A∙W   T∙R∙I∙A∙D ■
  564.  
  565. ──────────────────────────────────────────────────────────────────────────────
  566.